---
import { getDomains, getMessagesForDomain } from '@utils/collections/domains';
import { getServices } from '@utils/collections/services';
import { getContainers } from '@utils/collections/containers';
import { getMessages } from '@utils/messages';
import type { ExtendedDomain } from '@components/Grids/DomainGrid';
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
import DomainGrid from '@components/Grids/DomainGrid';
import ServiceGrid from '@components/Grids/ServiceGrid';
import MessageGrid from '@components/Grids/MessageGrid';
import { removeContentFromCollection } from '@utils/collections/util';

import type { CollectionEntry } from 'astro:content';
import type { CollectionMessageTypes } from '@types';

import { isVisualiserEnabled } from '@utils/feature';

import { ClientRouter, fade } from 'astro:transitions';
// Define valid types and their corresponding data fetchers
const VALID_TYPES = ['domains', 'services', 'messages'] as const;
type ValidType = (typeof VALID_TYPES)[number];

interface Service extends CollectionEntry<'services'> {
  sends: CollectionEntry<'events' | 'commands' | 'queries'>[];
  receives: CollectionEntry<'events' | 'commands' | 'queries'>[];
}

const { type, embeded = false } = Astro.props as { type: ValidType; embeded: boolean };

// Get data based on type
let items: Service[] | CollectionEntry<'commands'>[] | CollectionEntry<CollectionMessageTypes>[] = [];
let domains: ExtendedDomain[] = [];
let containers: CollectionEntry<'containers'>[] = [];

const getDomainsForArchitecturePages = async () => {
  const domains = await getDomains({ getAllVersions: false });

  // Get messages for each domain
  return Promise.all(
    domains.map(async (domain) => {
      const messages = await getMessagesForDomain(domain);
      // @ts-ignore we have to remove markdown information, as it's all send to the astro components. This reduced the page size.
      return {
        ...domain,
        sends: messages.sends.map((s) => ({ ...s, body: undefined, catalog: undefined })),
        receives: messages.receives.map((r) => ({ ...r, body: undefined, catalog: undefined })),
        catalog: undefined,
        body: undefined,
      } as ExtendedDomain;
    })
  );
};

if (type === 'domains' || type === 'services') {
  domains = await getDomainsForArchitecturePages();
}

if (type === 'services') {
  const services = await getServices({ getAllVersions: false });
  let filteredServices = services.map((s) => {
    // @ts-ignore we have to remove markdown information, as it's all send to the astro components. This reduced the page size.
    return {
      ...s,
      sends: (s.data.sends || []).map((s) => ({ ...s, body: undefined, catalog: undefined })),
      receives: (s.data.receives || []).map((r) => ({ ...r, body: undefined, catalog: undefined })),
      catalog: undefined,
      body: undefined,
    } as Service;
  }) as unknown as Service[];
  items = filteredServices;
} else if (type === 'messages') {
  const { events, commands, queries } = await getMessages({ getAllVersions: false, hydrateServices: false });
  const messages = [...events, ...commands, ...queries];
  items = removeContentFromCollection(messages) as unknown as CollectionEntry<CollectionMessageTypes>[];
  containers = await getContainers({ getAllVersions: false });
}
---

<VerticalSideBarLayout title={'EventCatalog'}>
  <div class="bg-white min-h-screen">
    <div class="max-w-[90em] mx-auto">
      <div class="px-6 py-6" transition:animate={fade({ duration: '0.4s' })}>
        {type === 'domains' && <DomainGrid domains={domains} embeded={embeded} client:load />}
        {
          type === 'services' && (
            <ServiceGrid
              domains={domains}
              services={items as unknown as Service[]}
              embeded={embeded}
              isVisualiserEnabled={isVisualiserEnabled()}
              client:load
            />
          )
        }
        {
          type === 'messages' && (
            <MessageGrid
              messages={items as CollectionEntry<CollectionMessageTypes>[]}
              embeded={embeded}
              containers={containers}
              isVisualiserEnabled={isVisualiserEnabled()}
              client:load
            />
          )
        }
      </div>
    </div>
    <ClientRouter />
  </div>
</VerticalSideBarLayout>
